#include "prot.h"
#include "paging_api.h"
#include "vaddr.h"

template<typename... Args>
u64 vaddr (unsigned pagingMode, Args... args)
{
  switch (pagingMode) {
    //case PM_32:  return vaddr32(args...);
    //case PM_PAE: return vaddrPae(args...);
    case PM_64:  return vaddr64(args...);
  }
  
  return 0;
}


u64 vaddr (std::vector<unsigned> address, unsigned pagingMode) {
  switch (address.size()) {
    case 3: return vaddr(pagingMode,
                         address[0],
                         address[1],
                         address[2]);
    case 4: return vaddr(pagingMode,
                         address[0],
                         address[1],
                         address[2],
                         address[3]);
    case 5: return vaddr(pagingMode,
                         address[0],
                         address[1],
                         address[2],
                         address[3],
                         address[4]);
  }
  
  return 0;
}

u64 vaddr64 (u16 i_pml4e, u16 i_pdpte, u32 offset)
{
  return (u64)i_pml4e << PML4E_64_SHIFT |
         (u64)i_pdpte << PDPTE_64_SHIFT |
         (u64)offset;
}

u64 vaddr64 (u16 i_pml4e, u16 i_pdpte, u16 i_pde, u32 offset)
{
  return vaddr64 ( i_pml4e, i_pdpte, 
                   (u32)i_pde << PDE_64_SHIFT | offset );
}

u64 vaddr64 (u16 i_pml4e, u16 i_pdpte, u16 i_pde, u16 i_pte, u16 offset)
{
  return vaddr64 ( i_pml4e, i_pdpte, i_pde,
                   (u32)i_pte << PTE_64_SHIFT | (u32)offset );
}